#ifndef __UTILS_CPP__
#define __UTILS_CPP__

#include <sstream>
#include <regex>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

using std::string;
using std::vector;

inline bool isEscape(char ch){
    return (ch == 'b') || (ch == 't') || (ch == 'n') || (ch == 'f') || (ch == 'r') || (ch == '\"') || (ch == '\\');
}

inline string toEscape(char ch){
    switch(ch){
        case 'b':
            return "\b";
        case 't':
            return "\t";
        case 'n':
            return "\n";
        case 'f':
            return "\f";
        case 'r':
            return "\r";
        case '\"':
            return "\"";
        case '\\':
            return "\\";
    }
    return "Invalid char "; // shall never reach
}

inline bool isOneWordOperator(char ch){
    string ops = "{};[]*+-/~%&^|,";
    return ops.find(ch) != string::npos;
}

template <typename Enumeration>
inline auto enum2Int(Enumeration const value) -> typename std::underlying_type<Enumeration>::type {
    return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}

inline string trim(const string &s) {
    if (s.empty())
        return s;
    int stPos = s.find_first_not_of(" ");
    if (stPos == string::npos)
        return "";
    return s.substr(stPos, s.find_last_not_of(" ") + 1);
}

string replace(string str, string reg1, string target){
    return std::regex_replace(str, std::regex(reg1), target);
}

std::vector<std::string> split(const std::string &in) {
    std::stringstream ss(in);
    vector<string> ret;
    string tmp;
    while(ss>>tmp){
        ret.push_back(tmp);
    }
    return ret;
    // std::regex re{delim};
    // // 调用 std::vector::vector (InputIterator first, InputIterator last,const allocator_type& alloc
    // // = allocator_type()) 构造函数,完成字符串分割
    // auto ret = std::vector<std::string>{std::sregex_token_iterator(in.begin(), in.end(), re, -1),
    //                                 std::sregex_token_iterator()};
}

template<typename Container_T, typename T>
bool contains(Container_T& container, T& value){
    for(auto i: container){
        if(i == value)
            return true;
    }
    return false;
}

template <typename Container_T, typename T>
int indexOf(Container_T &container, T& value) {
    for (int i = 0; i < container.size(); ++i){
        if(container[i] == value)
            return i;
    }
    return -1;
}

#endif